using System.IO.Ports;
using System.Text;
using TouchSocket.Core;
using TouchSocket.SerialPorts;
using TouchSocket.Sockets;

namespace AirCtrl.Wpf.Core;


public class CmdGroundClient : SingletonBase<CmdGroundClient>
{
    /// <summary>
    /// 地面站客户端
    /// </summary>
    public SerialPortClient GroundClient { get; set; } = new SerialPortClient();

    private IWaitingClient<ISerialPortClient,IReceiverResult> _waitingClient;
   

    public async Task Connect(string portName)
    {
        var client = GroundClient;
        await client.SafeCloseAsync();
        await client.SetupAsync(new TouchSocketConfig()
            .SetSerialPortOption(new SerialPortOption()
            {
                PortName = portName,
                BaudRate = 9600,
                DataBits = 8,
                Parity = Parity.None,
                StopBits = StopBits.One,
            }).SetSerialDataHandlingAdapter(() => new PeriodPackageAdapter()
                { CacheTimeout = TimeSpan.FromMilliseconds(100) })
        );
        await client.TryConnectAsync();
        _waitingClient = client.CreateWaitingClient(new WaitingOptions()
        {
            FilterFunc = received =>
            {
                return true;
            }
        });
    }

    public async Task<string> GetTemperature(double x, double y)
    {
        var res = await SendToAirClient(GroundCmdTokens.CmdTemperature, $"{x},{y}");
        return res;
    }
    public async Task<bool> StartCapture(double seconds)
    {
        var res = await SendToAirClient(GroundCmdTokens.CmdStartCapture, $"n {seconds}");
        return res.ToLower().Contains("ok");
    }
    public async Task<bool> StopCapture()
    {
        var res = await SendToAirClient(GroundCmdTokens.CmdStopCapture,"");
        return res.ToLower().Contains("ok");
    }

    private SemaphoreSlim _slim = new SemaphoreSlim(1,1);
    private Dictionary<string,string> _unResponseCmd = new Dictionary<string, string>();
    private async Task<string> SendToAirClient(string cmd, string msg)
    {
        try
        {
            LogHelper.Log($"SendToAirClient send cmd:{cmd} msg:{msg}");
            await _slim.WaitAsync();

            var d = cmd + Environment.NewLine + msg;
            var returnData = await _waitingClient.SendThenReturnAsync(d);
            var data = Encoding.UTF8.GetString(returnData);
            LogHelper.Log($"SendToAirClient response cmd:{cmd} response:{data}");
            var arr = data.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
            if (arr[0] == cmd)
            {
                return arr[1];
            }
        }
        catch (Exception e)
        {
            LogHelper.Log($"SendToAirClient send cmd:{cmd} exp:{e.Message}");
        }
        finally
        {
            _slim.Release();
        }
        return "";
    }
}

public class GroundCmdTokens
{
    /// <summary>
    /// 查询热成像坐标点温度
    /// <para>Request：X,Y；例如“123,22.4”</para>
    /// <para>Response：temperature；例如“30.5”</para>
    /// </summary>
    public const string CmdTemperature = "CmdTemperature";
    /// <summary>
    /// 拍照命令
    /// <para>Request：单次拍照：1；定时拍照:n 间隔秒数；例如“n 0.5”</para>
    /// <para>Response：ok</para>
    /// </summary>
    public const string CmdStartCapture = "CmdStartCapture";
    /// <summary>
    /// 停止拍照命令
    /// <para>Request：</para>
    /// <para>Response：ok</para>
    /// </summary>
    public const string CmdStopCapture = "CmdStopCapture";
}